{% load i18n %}
{% extends "base_generic.html" %}
{% block title %}Hexcolor{% endblock %}
{% block script %}
  <style type="text/css">
    body {
      background-color: #{{ color }};
    }
  </style>
{% endblock %}
{% block content %}
    <h1>{{ _("Extract colors from an image") }}</h1>
    <p>
      <input type="text" id="imgurl" placeholder="Enter or paste an image URL"/><br />
      <input type="button" id="btnLoad" value="Extract Colors" />
    </p>
    <canvas id="imageHolder" width="300" height="300"></canvas>
    <p>Extracted Color Palette</p>
    <div id="swatches"></div>
    <div id="info"><p>Info</p></div>

  <script>
    /* 
    Thanks to Warren Harrison!
    http://hungry-media.com/2010/09/html5canvas-fun-extracting-colors-from-images/
    */

    var ctx = document.getElementById('imageHolder').getContext('2d');
    var img = new Image();
    var info = document.getElementById('info');

    $('#btnLoad').click( function(){
      parseImg();
    });

    function parseImg(){
      var colors = new Array();
      $('div.swatch').remove();
      img.src = "/getimage/?image=" + $('#imgurl').val();
      ctx.width = 1000;
      ctx.height = 1000;
      ctx.clearRect(0,0,1000,1000);
      img.onload = function(){
        ctx.width = img.width;
        ctx.height = img.height;

        // once loaded, plop the image on the canvas
        ctx.drawImage(img, 0, 0);

        // load the image data into an array of pixel data (R, G, B, a)
        var imgd = ctx.getImageData( 0, 0, $('#imageHolder').width(), $('#imageHolder').height() );
        var pix = imgd.data;

        // build an array of each color value and respective number of pixels using it
        for( var i = 0; i < pix.length; i+=4 ){
          var colorString = pix[i] + ',' + pix[i+1] + ',' + pix[i+2] + ',' + pix[i+3];
          if( colors[colorString] ){
            colors[colorString]++;
          }else{
            colors[colorString] = 1;
          }
        }

        // sort the array with greatest count at top
        var sortedColors = sortAssoc(colors);
        var ctr = 0;
        var devVal = 30;
        var usedColors = []; // used to see if close color is already seen
        var isValid = false;

        // create a lovely palette of the 5 most used colors
        for( var clr in sortedColors ){
          // weed out colors close to those already seen
          var colorValues = clr.split(',');
          var hexVal = '';
          for( var i = 0; i < 3; i++ ){
            hexVal += decimalToHex(colorValues[i], 2);
          }
          isValid = true;
          for( var usedColor in usedColors ){
            var colorDevTtl = 0;
            var rgbaVals = usedColors[usedColor].split(',');
            for( var i = 0; i <= 3; i++ ){
              colorDevTtl += Math.abs( colorValues[i] - rgbaVals[i] );
            }
            if( colorDevTtl / 4 < devVal ){
              isValid = false;
              break;
            }
          }
          if( isValid ){
            var whtTxtStyle = '';
            if( hexVal == 'ffffff' ){ whtTxtStyle = '; color: #666'; }
            $('#swatches').append('<span class="colorBox" style="background: #' + hexVal + whtTxtStyle + ';"><a href="/color/' + hexVal + '/">#' + hexVal + '</a></div>');
            usedColors.push(clr);
            ctr++;
          }
          if( ctr > 10 ){
            break;
          }
        }
      }
      ctx.width = 300;
      ctx.height = 300;
    }

    // ref: http://bytes.com/topic/javascript/answers/153019-sorting-associative-array-keys-based-values
    function sortAssoc(aInput){
      var aTemp = [];
      for (var sKey in aInput)
        aTemp.push([sKey, aInput[sKey]]);
        aTemp.sort(function () {return arguments[1][1] - arguments[0][1]}
      );

      var aOutput = [];
      for (var nIndex = 0; nIndex < aTemp.length; nIndex++){
        aOutput[aTemp[nIndex][0]] = aTemp[nIndex][1];
      }
      return aOutput;
    }

    // ref: http://stackoverflow.com/questions/57803/how-to-convert-decimal-to-hex-in-javascript
    function decimalToHex(d, padding) {
      var hex = Number(d).toString(16);
      padding = typeof (padding) === "undefined" || padding === null ? padding = 2 : padding;

      while (hex.length < padding) {
        hex = "0" + hex;
      }
      return hex;
    }
  </script>

{% endblock %}
